package com.shanxia.codec.cmd;

import com.shanxia.codec.ProtocolDataBase;
import com.shanxia.codec.enums.DecodeEnum;
import lombok.Data;

import javax.swing.*;
import java.math.BigDecimal;
import java.util.Arrays;

import static com.shanxia.codec.CodeConstant.HUNDRED;
import static com.shanxia.codec.CodeConstant.PERCENT;
import static com.shanxia.codec.Decoder.*;

/**
 * S -> C
 * 服务器应答充电桩上报充电信息报文
 */
@Data
public class Cmd203 extends ProtocolDataBase {

    public static final int MIN_SIZE = 69;

    private int v1;
    private int v2;
    private int respCode;                           // 响应码
    private double balance;                         // 账户余额
    private double chargeRate;                      // 全时段费率
    private double serviceRate;                     // 服务费率
    private int pwdVerify;                          // 充电密码验证
    private int vinSign;                            // 验证VIN标志
    private int carNumVerify;                       // 车牌验证
    private int v3;                                 // 预留
    private String serial;                          // 流水号
    private String vin;                             // VIN

    public Cmd203(){
        super.setCmd(203);
    }

    public static Cmd203 decodeFromBase(ProtocolDataBase protocolDataBase) {
        Cmd203 cmd = new Cmd203();
        cmd.copyDataFrom(protocolDataBase);
        byte[] dataField = protocolDataBase.getDataField();
        //数据域长度
        if (dataField.length < MIN_SIZE) {
            cmd.setResult(DecodeEnum.InvalidData);
            return cmd;
        }
        int offset = 0;
        cmd.v1 = getUint16(dataField, offset);
        offset += 2;
        cmd.v2 = getUint16(dataField, offset);
        offset += 2;
        // 4字节响应码
        cmd.respCode = getInt32(dataField, offset);
        offset += 4;
        // 4字节用户余额
        cmd.balance = new BigDecimal(getInt32(dataField, offset)).multiply(PERCENT).doubleValue();
        offset += 4;
        // 2字节全时段电费费率
        cmd.chargeRate = new BigDecimal(getUint16(dataField, offset)).multiply(PERCENT).doubleValue();
        offset += 2;
        // 2字节服务费率
        cmd.serviceRate = new BigDecimal(getUint16(dataField, offset)).multiply(PERCENT).doubleValue();
        offset += 2;
        // 1字节充电密码验证
        cmd.pwdVerify = getUint8(dataField[offset++]);
        // 1字节验证VIN标志
        cmd.vinSign = getUint8(dataField[offset++]);
        // 1字节车牌验证
        cmd.carNumVerify = getUint8(dataField[offset++]);
        // 1字节预留
        cmd.v3 = getUint8(dataField[offset++]);
        // 32字节流水号
        cmd.serial = byteToAscii(Arrays.copyOfRange(dataField, offset, offset + 32), true);
        offset += 32;
        // 17字节VIN
        cmd.vin = byteToAscii(Arrays.copyOfRange(dataField, offset, offset + 17), true);
        return cmd;
    }

    @Override
    public byte[] getDataField() {
        byte[] data = new byte[MIN_SIZE];
        int offset = 0;
        getBytesAsUint16(data, offset, this.v1);
        offset += 2;
        getBytesAsUint16(data, offset, this.v2);
        offset += 2;
        // 4字节响应码
        intToBytesLittle(data, offset, this.respCode);
        offset += 4;
        // 4字节账户余额
        intToBytesLittle(data, offset, new BigDecimal(String.valueOf(balance)).multiply(HUNDRED).intValue());
        offset += 4;
        // 2字节全时段电费费率
        getBytesAsUint16(data, offset, new BigDecimal(String.valueOf(chargeRate)).multiply(HUNDRED).intValue());
        offset += 2;
        // 2字节全时段电费费率
        getBytesAsUint16(data, offset, new BigDecimal(String.valueOf(serviceRate)).multiply(HUNDRED).intValue());
        offset += 2;
        // 1充电密码验证
        data[offset++] = (byte) this.pwdVerify;
        // 1字节验证VIN标志
        data[offset++] = (byte) this.vinSign;
        // 1字节车牌验证
        data[offset++] = (byte) this.carNumVerify;
        // 1字节预留
        data[offset++] = (byte) this.v3;
        // 32字节流水号
        encodeAscii(data, this.serial, 32, offset);
        offset += 32;
        // 17字节VIN
        encodeAscii(data, this.serial, 17, 17);
        return data;
    }
}
